﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OOAD_Project_Engine.Application.Services;
using Microsoft.Xna.Framework;
using OOAD_Project_Engine.Foundation;
using OOAD_Project_Engine.Domain.Components;
using OOAD_Project_Engine.Domain.Entities;
using OOAD_Project_Engine.Foundation.Interfaces;
using OOAD_Project_Editor.Foundation.Script;
using System.Reflection;
using OOAD_Project_Engine.Domain.Factories;
using OOAD_Project_Editor.Foundation;
using OOAD_Project_Editor.Domain;

namespace OOAD_Project_Editor.Domain
{
    public class EditableSceneComponent : SceneComponent, IEditableSceneComponent
    {
        public event EventHandler OnUpdateFinished;

        public EditableSceneComponent(Game game, SceneScript script)
            : this(game)
        {
            string name = script.Name;
            foreach (EntityScript es in script.EntityScript)
            {
                IEntityComponent[] components = new IEntityComponent[es.EntityComponentScripts.Count];
                for (int i = 0; i < components.Length; i++)
                {
                    EntityComponentScript ecs = es.EntityComponentScripts[i];
                    components[i] = createComponent(ecs);
                }
                Entity e = Factory.Create(typeof(Entity), es.Name, components);
            }
        }

        IEntityComponent createComponent(EntityComponentScript ecs)
        {
            object[] parameters = ecs.ConstructorParameters.ToArray();
            IEntityComponent component = EntityComponentFactory.CreateComponent(ecs.GetComponentType(), parameters);
            Type t = component.GetType();
            foreach (CustomProperty p in ecs.CustomProperties)
            {
                PropertyInfo pi = t.GetProperty(p.Name);
                pi.SetValue(component, Convert.ChangeType(p.Value, pi.PropertyType), null);
            }
            return component;
        }

        public EditableSceneComponent(Game game)
            : base(game) { }

        public override void Draw(GameTime gameTime)
        {
            GameHelper.GetService<IGraphicService>().GraphicsDevice.Clear(Color.Black);
            base.Draw(gameTime);
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            if (OnUpdateFinished != null)
                OnUpdateFinished(this, new EventArgs());
            OnUpdateFinished = null;
        }

        public Entity TryGetByTransform(int x, int y)
        {
            List<IEntity> entities = Manager.FindAllWith<Sprite>();
            Vector2 pos = new Vector2(x, y);

            foreach (IEntity e in entities)
            {
                if ( SpriteAreaHelper.GetInstance().CheckPont(pos, e.Find<Sprite>()))
                    return e as Entity;
            }
            return null;
        }

        public Entity TryGetByName(string name)
        {
            return Manager.Find(name) as Entity;
        }

        public IDictionary<string, IEntity> AllEntitys
        {
            get
            {
                Dictionary<string, IEntity> dic = new Dictionary<string, IEntity>();
                foreach (IEntity e in Manager)
                {
                    dic.Add(e.Name, e);
                }
                return dic;
            }
        }

        public SceneScript ToScript()
        {
            return ScriptFactory.GetInstance().ToScript(this);
        }
    }
}
